package ch.nostromo.tiffanys.clients.chessmind;

import uk.ac.cam.cl.projectcharlie2010.engines.Engine;
import uk.ac.cam.cl.projectcharlie2010.game.GameController;
import uk.ac.cam.cl.projectcharlie2010.game.GameControllerResult;
import uk.ac.cam.cl.projectcharlie2010.game.player.PlayerEngine;

import ch.nostromo.tiffanys.engines.EngineSettings;
import ch.nostromo.tiffanys.game.GameControllerException;
import ch.nostromo.tiffanys.game.GameControllerListener;
import ch.nostromo.tiffanys.game.game.GameException;

/**
 * ChessMind engine wrapper.
 *
 * @author Bernhard von Gunten
 *
 */
public class ChessMind {

  /**
   * The used chess engine
   */
  public static final String DEFAULT_ENGINE = "ch.nostromo.tiffanys.engines.tiffanys.TiffanysEngine";

  /**
   * Compute next move for given position
   *
   * @param fen
   *          The current board as FEN
   * @param engineSettings
   *          The engine settings
   *
   * @return The game controller result containing the selected move, all scored moves and some stats.
   * @throws ClassNotFoundException
   *
   * @throws ClassNotFoundException
   *           The class not found exception
   * @throws GameException
   *           The game exception
   */
  @SuppressWarnings("unchecked")
  public static GameControllerResult computeNextMove(String fen, EngineSettings engineSettings) throws GameControllerException, ClassNotFoundException {
    Class<Engine> engineClass = (Class<Engine>) Class.forName(DEFAULT_ENGINE);
    PlayerEngine engine = new PlayerEngine(engineClass, engineSettings);
    GameController gc = new GameController(engine, engine, fen);
    return gc.computeNextMoveNow(false);
  }

  /**
   * Compute next move for given position
   *
   * @param fen
   *          The current board as FEN
   * @param engineSettings
   *          The engine settings
   *
   * @return The game controller result containing the selected move, all scored moves and some stats.
   * @throws ClassNotFoundException
   *
   * @throws ClassNotFoundException
   *           The class not found exception
   * @throws GameException
   *           The game exception
   */
  @SuppressWarnings("unchecked")
  public static GameController computeNextMove(String fen, EngineSettings engineSettings, GameControllerListener gameControllerListener) throws GameControllerException, ClassNotFoundException {
    Class<Engine> engineClass = (Class<Engine>) Class.forName(DEFAULT_ENGINE);
    PlayerEngine engine = new PlayerEngine(engineClass, engineSettings);
    GameController gc = new GameController(engine, engine, fen);
    gc.addGameControllerListener(gameControllerListener);
    gc.computeNextMove(false);
    return gc;
  }

  /**
   * Cancel running GameController (returns the best current Move to attached listeners)
   * @param gc GameController
   */
  public static void cancelMove(GameController gc) {
    gc.engineMoveNow();
  }


  /**
   * The main method, containing a simple example.
   *
   * @param args
   *          the arguments
   * @throws ClassNotFoundException
   */
  public static void main(String[] args) {
    // Current position (looking nice for black)
    String fen = "k7/r7/r7/8/8/8/p7/K7 b KQkq - 0 3";

    // Define the settings (5 sec / move)
    EngineSettings engineSettings = new EngineSettings();
    engineSettings.GAME_MODE = EngineSettings.GAME_MODE_FIXED_TIME_PER_MOVE;
    engineSettings.FIXED_TIME_PER_MOVE = 5;

    // Compute the result

    try {
      GameControllerResult gcr = computeNextMove(fen, engineSettings);
      System.out.println(gcr.getSelectedMove().getSanDescription());
    } catch (GameControllerException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

}
